﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Collections.ObjectModel;

namespace DocumentSearchServiceModel
{
    public class SearchResultItemCls
    {
        public string DocumentId = "";
        public string DocumentNo = "";
        public string Subject = "";
        public string Description = "";
        public string DocSigner = "";
        public string DocSignerId = "";

        public string DocType = "";
        public string DocTypeId = "";
        public string DocStatus = "";
        
        public string DocReleaseFrom = "";
        public string DocReleaseFromId = "";

        public string DocField = "";
        public string DocFieldId = "";

        public string SignDate;
        public string ReleaseDate;
        public string EffectedDate;
        public string EntryDate;
        public string UpdatedDate;
        public string Unicode;

        public bool Marked = true;
        public int IsPublic = 0;
        public int IsNew = 0;
        public int AttachedSearchable = 0;
        public int NeedApproved = 0;
    }



    public class SearchResultItemParser
    {
        public static string GetXml(SearchResultItemCls OSearchResultItem)
        {
            DataSet ds = new DataSet();
            ds.Tables.Add("xml");
            ds.Tables["xml"].Columns.Add("DocumentId");
            ds.Tables["xml"].Columns.Add("DocumentNo");
            ds.Tables["xml"].Columns.Add("Subject");
            ds.Tables["xml"].Columns.Add("Description");
            ds.Tables["xml"].Columns.Add("DocSigner");
            ds.Tables["xml"].Columns.Add("DocType");
            ds.Tables["xml"].Columns.Add("DocTypeId");
            ds.Tables["xml"].Columns.Add("DocStatus");
            ds.Tables["xml"].Columns.Add("DocReleaseFrom");
            ds.Tables["xml"].Columns.Add("SignDate");
            ds.Tables["xml"].Columns.Add("ReleaseDate");
            ds.Tables["xml"].Columns.Add("EffectedDate");
            ds.Tables["xml"].Columns.Add("EntryDate");
            ds.Tables["xml"].Columns.Add("UpdatedDate");
            ds.Tables["xml"].Columns.Add("Unicode");
            ds.Tables["xml"].Columns.Add("IsPublic");
            ds.Tables["xml"].Columns.Add("IsNew");
            ds.Tables["xml"].Columns.Add("AttachedSearchable");
            ds.Tables["xml"].Columns.Add("NeedApproved");
            ds.Tables["xml"].Rows.Add(
                new object[]{
                 OSearchResultItem.DocumentId,
                 OSearchResultItem.DocumentNo,
                 OSearchResultItem.Subject,
                 OSearchResultItem.Description, 
                 OSearchResultItem.DocSigner, 
                 OSearchResultItem.DocType,
                 OSearchResultItem.DocTypeId,
                 OSearchResultItem.DocStatus,
                 OSearchResultItem.DocReleaseFrom,
                 OSearchResultItem.SignDate,
                 OSearchResultItem.ReleaseDate,
                 OSearchResultItem.EffectedDate,
                 OSearchResultItem.EntryDate,
                 OSearchResultItem.UpdatedDate,
                 OSearchResultItem.Unicode,
                 OSearchResultItem.IsPublic,
                 OSearchResultItem.IsNew,
                 OSearchResultItem.AttachedSearchable,
                 OSearchResultItem.NeedApproved
            });
            return ds.GetXml();
        }


        public static string GetXml(SearchResultItemCls[] OSearchResultItems)
        {
            DataSet ds = new DataSet();
            ds.Tables.Add("xml");
            ds.Tables["xml"].Columns.Add("DocumentId");
            ds.Tables["xml"].Columns.Add("DocumentNo");
            ds.Tables["xml"].Columns.Add("Subject");
            ds.Tables["xml"].Columns.Add("Description");
            ds.Tables["xml"].Columns.Add("DocSigner");
            ds.Tables["xml"].Columns.Add("DocType");
            ds.Tables["xml"].Columns.Add("DocTypeId");
            ds.Tables["xml"].Columns.Add("DocStatus");
            ds.Tables["xml"].Columns.Add("DocReleaseFrom");
            ds.Tables["xml"].Columns.Add("SignDate");
            ds.Tables["xml"].Columns.Add("ReleaseDate");
            ds.Tables["xml"].Columns.Add("EffectedDate");
            ds.Tables["xml"].Columns.Add("EntryDate");
            ds.Tables["xml"].Columns.Add("UpdatedDate");
            ds.Tables["xml"].Columns.Add("Unicode");
            ds.Tables["xml"].Columns.Add("IsPublic");
            ds.Tables["xml"].Columns.Add("IsNew");
            ds.Tables["xml"].Columns.Add("AttachedSearchable");
            ds.Tables["xml"].Columns.Add("NeedApproved");
            for (int iIndex = 0; iIndex < OSearchResultItems.Length; iIndex++)
            {
                SearchResultItemCls OSearchResultItem = OSearchResultItems[iIndex];
                ds.Tables["xml"].Rows.Add(
                    new object[]{
                         OSearchResultItem.DocumentId,
                         OSearchResultItem.DocumentNo,
                         OSearchResultItem.Subject,
                         OSearchResultItem.Description, 
                         OSearchResultItem.DocSigner, 
                         OSearchResultItem.DocType,
                         OSearchResultItem.DocTypeId,
                         OSearchResultItem.DocStatus,
                         OSearchResultItem.DocReleaseFrom,
                         OSearchResultItem.SignDate,
                         OSearchResultItem.ReleaseDate,
                         OSearchResultItem.EffectedDate,
                         OSearchResultItem.EntryDate,
                         OSearchResultItem.UpdatedDate,
                         OSearchResultItem.Unicode,
                         OSearchResultItem.IsPublic,
                         OSearchResultItem.IsNew,
                         OSearchResultItem.AttachedSearchable,
                         OSearchResultItem.NeedApproved
                    });
            }
            return ds.GetXml();
        }


        public static SearchResultItemCls Parser(string Xml)
        {
            DataSet ds = new DataSet();
            ds.ReadXml(new StringReader(Xml));
            SearchResultItemCls OSearchResultItemCls = new SearchResultItemCls();
            try
            {
                OSearchResultItemCls.DocumentId = ds.Tables[0].Rows[0]["DocumentId"].ToString();
            }
            catch { }
           
            try
            {
                OSearchResultItemCls.DocumentNo = ds.Tables[0].Rows[0]["DocumentNo"].ToString();
            }
            catch { }
            try
            {
                OSearchResultItemCls.Subject = ds.Tables[0].Rows[0]["Subject"].ToString();
            }
            catch { }
            try
            {
                OSearchResultItemCls.Description = ds.Tables[0].Rows[0]["Description"].ToString();
            }
            catch { }
            try
            {
                OSearchResultItemCls.DocSigner = ds.Tables[0].Rows[0]["DocSigner"].ToString();
            }
            catch { }
            try
            {
                OSearchResultItemCls.DocType = ds.Tables[0].Rows[0]["DocType"].ToString();
            }
            catch { }
            try
            {
                OSearchResultItemCls.DocTypeId = ds.Tables[0].Rows[0]["frkDocTypeId"].ToString();
                OSearchResultItemCls.DocTypeId = OSearchResultItemCls.DocTypeId.Replace("$", "");
            }
            catch { }
            try
            {
                OSearchResultItemCls.DocStatus = ds.Tables[0].Rows[0]["DocStatus"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.DocReleaseFrom = ds.Tables[0].Rows[0]["DocReleaseFrom"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.SignDate = ds.Tables[0].Rows[0]["SignDate"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.ReleaseDate = ds.Tables[0].Rows[0]["ReleaseDate"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.EffectedDate = ds.Tables[0].Rows[0]["EffectedDate"].ToString();
            }
            catch { }


            try
            {
                OSearchResultItemCls.EntryDate = ds.Tables[0].Rows[0]["EntryDate"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.UpdatedDate = ds.Tables[0].Rows[0]["UpdatedDate"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.Unicode = ds.Tables[0].Rows[0]["Unicode"].ToString();
            }
            catch { }

            try
            {
                OSearchResultItemCls.IsPublic = int.Parse(ds.Tables[0].Rows[0]["IsPublic"].ToString());
            }
            catch { }
            try
            {
                OSearchResultItemCls.IsNew = int.Parse(ds.Tables[0].Rows[0]["IsNew"].ToString());
            }
            catch { }
            try
            {
                OSearchResultItemCls.AttachedSearchable = int.Parse(ds.Tables[0].Rows[0]["AttachedSearchable"].ToString());
            }
            catch { }
            try
            {
                OSearchResultItemCls.NeedApproved = int.Parse(ds.Tables[0].Rows[0]["NeedApproved"].ToString());
            }
            catch { }
            return OSearchResultItemCls;
        }


        public static SearchResultItemCls[] ParserFromMultiRow(string Xml)
        {
            if (string.IsNullOrEmpty(Xml))
            {
                return new SearchResultItemCls[0];
            }
            DataSet ds = new DataSet();
            ds.ReadXml(new StringReader(Xml));
            if (ds.Tables.Count == 0)
            {
                return new SearchResultItemCls[0];
            }

            ds.Tables["xml"].Columns.Add("DocumentId");
            ds.Tables["xml"].Columns.Add("DocumentNo");
            ds.Tables["xml"].Columns.Add("Subject");
            ds.Tables["xml"].Columns.Add("Description");
            ds.Tables["xml"].Columns.Add("DocSigner");
            ds.Tables["xml"].Columns.Add("DocType");
            ds.Tables["xml"].Columns.Add("DocTypeId");
            ds.Tables["xml"].Columns.Add("DocStatus");
            ds.Tables["xml"].Columns.Add("DocReleaseFrom");
            ds.Tables["xml"].Columns.Add("SignDate");
            ds.Tables["xml"].Columns.Add("ReleaseDate");
            ds.Tables["xml"].Columns.Add("EffectedDate");
            ds.Tables["xml"].Columns.Add("EntryDate");
            ds.Tables["xml"].Columns.Add("UpdatedDate");
            ds.Tables["xml"].Columns.Add("Unicode");
            ds.Tables["xml"].Columns.Add("IsPublic");
            ds.Tables["xml"].Columns.Add("IsNew");
            ds.Tables["xml"].Columns.Add("AttachedSearchable");
            ds.Tables["xml"].Columns.Add("NeedApproved");

            SearchResultItemCls[] OSearchResultItems = new SearchResultItemCls[ds.Tables[0].Rows.Count];
            for (int iIndex = 0; iIndex < OSearchResultItems.Length; iIndex++)
            {
                OSearchResultItems[iIndex] = new SearchResultItemCls();
                try
                {
                    OSearchResultItems[iIndex].DocumentId = ds.Tables[0].Rows[iIndex]["DocumentId"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].DocumentNo = ds.Tables[0].Rows[iIndex]["DocumentNo"].ToString();
                }
                catch { }
                try
                {
                    OSearchResultItems[iIndex].Subject = ds.Tables[0].Rows[iIndex]["Subject"].ToString();
                }
                catch { }
                try
                {
                    OSearchResultItems[iIndex].Description = ds.Tables[0].Rows[iIndex]["Description"].ToString();
                }
                catch { }
                try
                {
                    OSearchResultItems[iIndex].DocSigner = ds.Tables[0].Rows[iIndex]["DocSigner"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].DocType = ds.Tables[0].Rows[iIndex]["DocType"].ToString();
                }
                catch { }
                try
                {
                    OSearchResultItems[iIndex].DocTypeId = ds.Tables[0].Rows[iIndex]["frkDocTypeId"].ToString();
                }
                catch { }
                try
                {
                    OSearchResultItems[iIndex].DocStatus = ds.Tables[0].Rows[iIndex]["DocStatus"].ToString();
                }
                catch { }



                try
                {
                    OSearchResultItems[iIndex].DocReleaseFrom = ds.Tables[0].Rows[iIndex]["DocReleaseFrom"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].SignDate = ds.Tables[0].Rows[iIndex]["SignDate"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].ReleaseDate = ds.Tables[0].Rows[iIndex]["ReleaseDate"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].EffectedDate = ds.Tables[0].Rows[iIndex]["EffectedDate"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].EntryDate = ds.Tables[0].Rows[iIndex]["EntryDate"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].UpdatedDate = ds.Tables[0].Rows[iIndex]["UpdatedDate"].ToString();
                }
                catch { }


                try
                {
                    OSearchResultItems[iIndex].Unicode = ds.Tables[0].Rows[iIndex]["Unicode"].ToString();
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].IsPublic = int.Parse(ds.Tables[0].Rows[iIndex]["IsPublic"].ToString());
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].IsNew = int.Parse(ds.Tables[0].Rows[iIndex]["IsNew"].ToString());
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].AttachedSearchable = int.Parse(ds.Tables[0].Rows[iIndex]["AttachedSearchable"].ToString());
                }
                catch { }

                try
                {
                    OSearchResultItems[iIndex].NeedApproved = int.Parse(ds.Tables[0].Rows[iIndex]["NeedApproved"].ToString());
                }
                catch { }
            }
            return OSearchResultItems;
        }
    }



    public class SearchResultCls
    {
        public Collection<SearchResultItemCls> SearchResultItems = new Collection<SearchResultItemCls> { };
        public int TotalFound = 0;
        public int PageIndex = 0;
        public int MaxPage = 0;
        public bool SearchOk = false;
        public string InfoMessage = "";
        public string QuerySearch = "";
        public string PaggingText = "";
        public int StartIndex = 0;
    }



    public class SearchParamCls
    {
        public string GroupDataId;
        public bool   ActiveGroupData;

        public bool ActiveIsNew;

        public string SearchDocumentNo;
        public bool ActiveSearchDocumentNo = false;

        public bool ActiveFullTextSearch = false;
        public string fullTextSearchKeyword = "";

        public int PublishingStatus=2;
        public int Searchable = 2;

        public int Status = 2;
        
        public string SearchSubject;
        public bool ActiveSearchSubject = false;
        public bool ActiveSplitSearch = false;

        public string SearchDocType;
        public bool ActiveSearchDocType = false;

        public bool ActiveLimitDocumentNo = false;
        public string[] LimitDocumentNo = new string[0];

        public string SearchYearRangeFrom;
        public string SearchYearRangeTo;
        public bool ActiveSearchYearRange = false;


        public string SearchDocSigner;
        public bool ActiveSearchDocSigner = false;

        public string GroupDataFolderId;
        public bool ActiveGroupDataFolderId = false;


        public string SearchDocReleaseFrom;
        public bool ActiveSearchDocReleaseFrom = false;

        public string SearchDocField;
        public bool ActiveSearchDocField = false;

        public bool SearchSignDate = false;
        public string VnFromSignDate;
        public string VnToSignDate;

        public bool SearchReleaseDate = false;
        public string VnFromReleaseDate;
        public string VnToReleaseDate;

        public bool SearchEffectedDate = false;
        public string VnFromEffectedDate;
        public string VnToEffectedDate;

        public bool SearchEndEffectedDate = false;
        public string VnEndFromEffectedDate;
        public string VnEndToEffectedDate;
        
        public int PageSize = 25;
        public int PageIndex = 0;
        public int MaxFilesToRetrieve = 0;
        public int TimeoutSeconds = 0;
        public string IndexesToSearch = "";
        public string IndexesToSearchAttachDoc = "";
        public bool   IncludeBodyResult = false;
        public string SortField = "";
        public string SortType = "ASC";
        public string JumpPageJavascript = "NextPage";

        public string DataRoot = "";
    }


    public class SearchParser
    {
        public static string[] ConvertSearchDate(string VNDate)
        {
            string[] Items = VNDate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            return Items;
        }


        static string ProcessDate(string SDate)
        {
            string[] Items = SDate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            string MS = "";
            if(Items[1].Equals("01"))MS="jan";
            if(Items[1].Equals("02"))MS="feb";
            if(Items[1].Equals("03"))MS="mar";
            if(Items[1].Equals("04"))MS="apr";
            if(Items[1].Equals("05"))MS="may";
            if(Items[1].Equals("06"))MS="jun";
            if(Items[1].Equals("07"))MS="jul";
            if(Items[1].Equals("08"))MS="aug";
            if(Items[1].Equals("09"))MS="sep";
            if(Items[1].Equals("10"))MS="oct";
            if(Items[1].Equals("11"))MS="nov";
            if(Items[1].Equals("12"))MS="dec";

            string RValue = MS+ " "+ Items[2] + " " + Items[0];
            return RValue;
        }


        static string ProcessDateFrom(string Year)
        {
            string RValue = "jan" + " 01  " + Year;
            return RValue;
        }

        static string ProcessDateTo(string Year)
        {
            string RValue = "dec" + " 31 " + Year;
            return RValue;
        }

        public static string GetSearchCondition(SearchParamCls OSearchParam)
        {
            string SearchQuery = " (Info/IsPublic contains 1)";

            if (OSearchParam.PublishingStatus == 2)
            {
                SearchQuery = " ((Info/IsPublic contains 1) or (Info/IsPublic contains 0))";
            }
            if (OSearchParam.PublishingStatus == 0)
            {
                SearchQuery = " (Info/IsPublic contains 0)";
            }
            if (OSearchParam.PublishingStatus == 1)
            {
                SearchQuery = " (Info/IsPublic contains 1)";
            }


            if (OSearchParam.Searchable == 2)
            {
                //SearchQuery = " ((Info/AttachedSearchable contains 1) or (Info/AttachedSearchable contains 0))";
            }
            if (OSearchParam.Searchable == 0)
            {
                SearchQuery = " (Info/AttachedSearchable contains 0)";
            }
            if (OSearchParam.Searchable == 1)
            {
                SearchQuery = " (Info/AttachedSearchable contains 1)";
            }



            if (OSearchParam.Status == 2)
            {
                //SearchQuery = " ((Info/AttachedSearchable contains 1) or (Info/AttachedSearchable contains 0))";
            }
            if (OSearchParam.Status == 0)
            {
                SearchQuery = " (Info/DocStatus contains 0)";
            }
            if (OSearchParam.Status == 1)
            {
                SearchQuery = " (Info/DocStatus contains 1)";
            }

            if (OSearchParam.ActiveGroupDataFolderId)
            {
                SearchQuery += " AND  (Info/frkGroupDataFolderId contains $" + OSearchParam.GroupDataFolderId + "$)";
            }

            if (OSearchParam.ActiveIsNew)
            {
                //SearchQuery = " (Info/IsNew contains 1)";
                //string SDateNow = System.DateTime.Now.ToString("dd/MM/yyyy");
                //string SPrevDateNow = System.DateTime.Now.AddMonths(-2).ToString("dd/MM/yyyy");
                //SearchQuery += " AND  (Info/SearchReleaseDate contains date(" + ProcessDate(SPrevDateNow) + " to " + ProcessDate(SDateNow) + ")) ";
                if (OSearchParam.LimitDocumentNo != null)
                {
                    if (OSearchParam.LimitDocumentNo.Length > 0)
                    {
                        SearchQuery += " AND  (";
                        for (int iIndex = 0; iIndex < OSearchParam.LimitDocumentNo.Length; iIndex++)
                        {
                            SearchQuery += " (Info/DataAlias contains " + OSearchParam.LimitDocumentNo[iIndex]+") ";
                            if (iIndex < OSearchParam.LimitDocumentNo.Length - 1)
                            {
                                SearchQuery += " OR ";
                            }
                        }
                        SearchQuery += ")";
                    }
                }
            }
            if (OSearchParam.ActiveGroupData)
            {
                SearchQuery += " AND  (Info/frkGroupDataId contains $" + OSearchParam.GroupDataId + "$)";
            }
            if (OSearchParam.ActiveSearchDocumentNo)
            {
                SearchQuery += " AND  (Info/DataAlias contains " + OSearchParam.SearchDocumentNo + ")";
            }
            if (OSearchParam.ActiveSearchDocType)
            {
                SearchQuery += " AND  (Info/frkDocTypeId contains $" + OSearchParam.SearchDocType + "$)";
            }
            if (OSearchParam.ActiveSearchDocField)
            {
                SearchQuery += " AND  (Info/frkDocFieldId contains $" + OSearchParam.SearchDocField + "$)";
            }
            if (OSearchParam.ActiveSearchDocReleaseFrom)
            {
                SearchQuery += " AND  (Info/frkDocReleaseFromId contains $" + OSearchParam.SearchDocReleaseFrom + "$)";
            }
            if (OSearchParam.ActiveSearchDocSigner)
            {
                SearchQuery += " AND  (Info/frkDocSignerId contains $" + OSearchParam.SearchDocSigner + "$)";
            }
            if (OSearchParam.ActiveSearchYearRange)
            {
                //SearchQuery += " AND  (Info/frkYearRangeId contains $" + OSearchParam.SearchYearRange + "$)";

                SearchQuery += " AND  (Info/SearchReleaseDate contains date(" + ProcessDateFrom(OSearchParam.SearchYearRangeFrom) + " to " + ProcessDateTo(OSearchParam.SearchYearRangeTo) + ")) ";
            }
            if (OSearchParam.ActiveSearchSubject)
            {
                OSearchParam.SearchSubject = OSearchParam.SearchSubject.Trim().Replace("  ", " ");
                if (OSearchParam.ActiveSplitSearch)
                {
                    string[] Subjects = OSearchParam.SearchSubject.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    string SearchSubject = "";
                    if (Subjects.Length <= 1)
                    {
                        SearchSubject = OSearchParam.SearchSubject;
                    }
                    else
                    {
                        for (int iIndex = 0; iIndex < Subjects.Length; iIndex++)
                        {
                            SearchSubject = SearchSubject + Subjects[iIndex];
                            if (iIndex < Subjects.Length - 1)
                            {
                                SearchSubject += " W/10 ";
                            }
                        }
                    }
                    SearchQuery += " AND  ( (Info/Subject contains " + SearchSubject + ") or (Info/Description contains " + SearchSubject + "))";
                }
                else
                {
                    SearchQuery += " AND  ( (Info/Subject contains " + OSearchParam.SearchSubject + ") or (Info/Description contains " + OSearchParam.SearchSubject + "))";
                }
            }
            if (OSearchParam.SearchSignDate)
            {
                SearchQuery += " AND  (Info/SearchSignDate contains date(" + ProcessDate(OSearchParam.VnFromSignDate) + " to " + ProcessDate(OSearchParam.VnToSignDate) + ")) ";
            }
            if (OSearchParam.SearchReleaseDate)
            {
                SearchQuery += " AND  (Info/SearchReleaseDate contains date(" + ProcessDate(OSearchParam.VnFromReleaseDate) + " to " + ProcessDate(OSearchParam.VnToReleaseDate) + ")) ";
            }
            if (OSearchParam.SearchEffectedDate)
            {
                SearchQuery += " AND  (Info/SearchEffectedDate contains date(" + ProcessDate(OSearchParam.VnFromEffectedDate) + " to " + ProcessDate(OSearchParam.VnToEffectedDate) + ")) ";
            }
            if (OSearchParam.SearchEndEffectedDate)
            {
                SearchQuery += " AND  (Info/SearchEndEffectedDate contains date(" + ProcessDate(OSearchParam.VnEndFromEffectedDate) + " to " + ProcessDate(OSearchParam.VnEndToEffectedDate) + ")) ";
            }
            SearchQuery = SearchQuery.Trim();
            return SearchQuery;
        }
    }
}
